﻿using System;
using System.Collections.Generic;

namespace Sinacor.Infra.Core.Licensing.Business
{
    public class Licenca
    {
        #region Attributes
        private Business.Historico _businessHistorico;
        private Business.Empresa _businessEmpresa;
        private Business.Modulo _businessModulo; 

        private Data.Licenca _resourceAccess;
        private object locker = new object();
        #endregion

        #region Constructor

        public Licenca()
        {
            _businessHistorico = new Business.Historico();
            _businessEmpresa = new Business.Empresa();
            _businessModulo = new Business.Modulo(); 

            _resourceAccess = new Data.Licenca();
          
        }

        #endregion

        #region Methods

        public Sinacor.Infra.Core.Licensing.Licensing Incluir(Sinacor.Infra.Core.Licensing.Licensing library)
        {
           library.Id = _resourceAccess.SelecionarProximoIdLicenca();
           LicensingCompanyModule licensingCompanyModule;

           _resourceAccess.InserirLicenca(library);

           library = InserirLicencaHistorico(library); 

           library.Description.LicensingId = library.Id.Value;
           library.Description.TypeDescription = library.Description.TypeDescription;
           library.Description.Period = library.Created.Value;

           library.Description = _businessHistorico.Incluir(library.Description);

           if (library.Companies != null)
           {
               Company company;
               foreach (var iCompany in library.Companies)
               {
                   company = _businessEmpresa.Incluir(iCompany);

                   foreach (var modulo in iCompany.Modules)
                   {
                       licensingCompanyModule = new LicensingCompanyModule
                       {
                           LicensingId = library.Id.Value,
                           DescriptionLicensingId = library.Description.IdVersionLicensing.Value,
                           CompanyId = company.CompanyId.Value,
                           ModuleId = modulo.ID,
                           GoodThru = modulo.GoodThru,
                           Plus = modulo.Plus
                       };

                       _resourceAccess.InserirLicencaEmpresaModulo(licensingCompanyModule);

                       _resourceAccess.InserirLicencaEmpresaHistorico(licensingCompanyModule);
                   }
               }
           }

            return library;
        }

        public Sinacor.Infra.Core.Licensing.Licensing InserirLicencaHistorico(Sinacor.Infra.Core.Licensing.Licensing library)
        {
            library.Description.IdVersionLicensing = SelecionarProximoIdLicencaHistorico();

            _resourceAccess.InserirLicencaHistorico(library);

            return library;
        }

        public void Alterar(Sinacor.Infra.Core.Licensing.Licensing library)
        {
            LicensingCompanyModule licensingCompanyModule;
           
            #region Alterar Licença
            _resourceAccess.AlterarLicenca(library);
            #endregion

            #region Historico

            library = InserirLicencaHistorico(library); 
            
            library.Description.LicensingId = library.Id.Value;
            //library.Description.Period = library.Created.Value;
            library.Description.TypeDescription = library.Description.TypeDescription;
                        
            //Atualiza o Historico
            library.Description = _businessHistorico.Incluir(library.Description);
                                    
            licensingCompanyModule = new LicensingCompanyModule();

            licensingCompanyModule.LicensingId = library.Id.Value;

            _businessEmpresa.ExcluirLicencaEmpresaModulo(licensingCompanyModule);
            
            #endregion                       

            #region Empresa e Modulo
            Company companyI;
            foreach (Company company in library.Companies)
            {
                companyI = _businessEmpresa.Incluir(company);

                foreach (var modulo in company.Modules)
                {    
                    licensingCompanyModule.DescriptionLicensingId = library.Description.Id.Value;
                    licensingCompanyModule.CompanyId = companyI.CompanyId.Value;
                    licensingCompanyModule.ModuleId = modulo.ID;

                    licensingCompanyModule.GoodThru = modulo.GoodThru;
                    licensingCompanyModule.Plus = modulo.Plus;
                    
                    _resourceAccess.InserirLicencaEmpresaModulo(licensingCompanyModule);
                    
                }
                foreach (var modulo in company.Modules)
                {
                    licensingCompanyModule.DescriptionLicensingId = library.Description.IdVersionLicensing.Value;
                    licensingCompanyModule.CompanyId = companyI.CompanyId.Value;
                    licensingCompanyModule.ModuleId = modulo.ID;

                    licensingCompanyModule.GoodThru = modulo.GoodThru;
                    licensingCompanyModule.Plus = modulo.Plus;

                    _resourceAccess.InserirLicencaEmpresaHistorico(licensingCompanyModule);
                }

            }
            #endregion
        }

        public void Excluir(Sinacor.Infra.Core.Licensing.Licensing library)
        {
            _resourceAccess.ExcluirLicenca(library);

            library = InserirLicencaHistorico(library); 

            library.Description.LicensingId  = library.Id.Value ;
            library.Description.Period = library.Created.Value; 
            library.Description.TypeDescription =  Sinacor.Infra.Core.Licensing.TypeDescription.Excluir;
            
            library.Description = _businessHistorico.Incluir(library.Description);

        }

       // public void InserirLicencaHistorico(Sinacor.Infra.Core.Licensing.Licensing library)
        //{
            //library.Description.LicensingId = SelecionarProximoIdLicencaHistorico();

            //_resourceAccess.InserirLicencaHistorico(library);

            //LicensingCompanyModule licensingCompanyModule = new LicensingCompanyModule
            //{
            //    LicensingId = library.Id.Value,
            //    CompanyId = company.CompanyId,
            //    ModuleId = modulo.ID,
            //    GoodThru = modulo.GoodThru,
            //    Plus = modulo.Plus
            //};

            //_resourceAccess.InserirLicencaEmpresaHistorico(licensingCompanyModule);

            ////LicensingCompanyModule 
            ////_resourceAccess.InserirLicencaEmpresaModulo(library);

            //library.Description.LicensingId = library.Id.Value; 

            //_resourceAccessHistorico.Incluir(library.Description);

       // }

        public void ExcluirLicencaHistorico(Sinacor.Infra.Core.Licensing.Licensing library)
        {
            _resourceAccess.ExcluirLicencaHistorico(library);
        }

        public void RestaurarEmpresaModulo(Sinacor.Infra.Core.Licensing.Licensing library)
        {
            _resourceAccess.RestaurarEmpresaModulo(library);
        }

        public List<Sinacor.Infra.Core.Licensing.Licensing> Selecionar(Sinacor.Infra.Core.Licensing.Licensing library)
        {
            List<Sinacor.Infra.Core.Licensing.Licensing> retorno;

            retorno = _resourceAccess.Selecionar(library);

            return retorno;
        }

        public Sinacor.Infra.Core.Licensing.Licensing SelecionarLicencaAtual(Sinacor.Infra.Core.Licensing.Licensing library)
        {
            Sinacor.Infra.Core.Licensing.Licensing retorno;

            retorno = _resourceAccess.SelecionarLicencaAtual(library);

            return retorno;
        }

        public List<Sinacor.Infra.Core.Licensing.Licensing> SelecionarHistorico(Sinacor.Infra.Core.Licensing.Licensing library)
        {
            List<Sinacor.Infra.Core.Licensing.Licensing> retorno;

            retorno = _resourceAccess.SelecionarHistorico(library);

            return retorno;
        }
        
        private int SelecionarProximoIdLicenca()
        {
            int nextId = 0;

            lock (locker)
            {
                nextId = _resourceAccess.SelecionarProximoIdLicenca();
            }

            return nextId;
        }

        private int SelecionarProximoIdLicencaHistorico()
        {
            int nextId = 0;

            lock (locker)
            {
                nextId = _resourceAccess.SelecionarProximoIdLicencaHistorico();
            }

            return nextId;
        }

        public Sinacor.Infra.Core.Licensing.Licensing SelecionarEmpresaHistorico(Sinacor.Infra.Core.Licensing.LicensingCompanyModule library)
        {
            Sinacor.Infra.Core.Licensing.Licensing retorno;

            retorno = _resourceAccess.SelecionarEmpresaHistorico(library);

            return retorno;
        }


        public void Restaurar(Sinacor.Infra.Core.Licensing.Licensing library)
        {
            LicensingCompanyModule licensingCompanyModule;
            Licensing licensing;

            #region Alterar Licença
            _resourceAccess.AlterarLicenca(library);
            #endregion

            #region Historico             
            
            library.Description.LicensingId = library.Id.Value;
            library.Description.Period = library.Created.Value;
            library.Description.TypeDescription = TypeDescription.Restaurar;

            library = InserirLicencaHistorico(library);

            licensingCompanyModule = new LicensingCompanyModule();
            licensingCompanyModule.LicensingId = library.Id.Value;  
            licensingCompanyModule.DescriptionLicensingId = library.Description.Id.Value;

            library.Description = _businessHistorico.Incluir(library.Description);
                        
            #endregion

            #region Excluir Licença Empresa Modulo
            ExcluirLicencaHistorico(library);
            #endregion

            #region Empresa e Modulo                
                licensing = SelecionarEmpresaHistorico(licensingCompanyModule);
                licensing.Id = licensingCompanyModule.LicensingId;  

                foreach (var company in licensing.Companies)
                {
                    licensingCompanyModule.CompanyId = company.CompanyId.Value;

                    foreach (var module in company.Modules)
                    {
                        licensingCompanyModule.ModuleId = module.ID;
                        licensingCompanyModule.GoodThru = module.GoodThru;
                        licensingCompanyModule.Plus = module.Plus;

                        _resourceAccess.InserirLicencaEmpresaModulo(licensingCompanyModule); 
                    }                     
                }

            #endregion
        }

        #endregion
    }
}
